// storageModel.go
package models

import (
	"context"
	"fmt"

	"log"
	"myk8s/common"
	"strings"

	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	//"k8s.io/apimachinery/pkg/runtime"
	//"sigs.k8s.io/yaml"
)

type Storageclass struct {
	StorageclassName string `json:"storageclassName"`
	Provisioner      string `json:"provisioner"`   //提供者
	Parameters       string `json:"parameters"`    //参数
	ReclaimPolicy    string `json:"reclaimPolicy"` //回收策略
	Labels           string `json:"labels"`
	Annotations      string `json:"annotations"` //注解
	CreateTime       string `json:"createTime"`
}

type PersistentVolume struct {
	PvName          string `json:"pvName"`
	Capacity        string `json:"capacity"`        //容量
	AccessMode      string `json:"accessMode"`      //访问模式
	PvReclaimPolicy string `json:"pvReclaimPolicy"` //回收策略
	StorageClass    string `json:"storageClass"`    //存储类型
	Status          string `json:"status"`          //状态
	ClaimRef        string `json:"claimRef"`        //绑定存储申明
	Labels          string `json:"labels"`
	Annotations     string `json:"annotations"` //注解
	CreateTime      string `json:"createTime"`
}

type PersistentVolumeClaim struct {
	PvcName      string `json:"pvcName"`
	NameSpace    string `json:"nameSpace"`
	Capacity     string `json:"capacity"`     //容量
	AccessMode   string `json:"accessMode"`   //访问模式
	StorageClass string `json:"storageClass"` //存储类型
	Status       string `json:"status"`       //状态
	VolumeName   string `json:"volumeName"`   //关联存储卷
	Labels       string `json:"labels"`
	Annotations  string `json:"annotations"` //注解
	CreateTime   string `json:"createTime"`
}

func StorageclassList(kubeconfig string) ([]Storageclass, error) {
	clientset := common.ClientSet(kubeconfig)
	storageclassList, err := clientset.StorageV1().StorageClasses().List(context.TODO(), metav1.ListOptions{})
	if err != nil {
		log.Printf("list deployment error, err:%v\n", err)
	}
	var bbb = make([]Storageclass, 0)
	for _, sc := range storageclassList.Items {
		var parms string
		for kk, vv := range sc.Parameters {
			parms += fmt.Sprintf("%s:%s,", kk, vv)
		}

		var labelsStr string
		for kk, vv := range sc.Labels {
			labelsStr += fmt.Sprintf("%s:%s,", kk, vv)
		}
		var annotationsStr string
		for k2, v2 := range sc.Annotations {
			annotationsStr += fmt.Sprintf("%s:%s,", k2, v2)
		}

		Items := &Storageclass{
			StorageclassName: sc.Name,
			Provisioner:      sc.Provisioner,
			Parameters:       parms,
			ReclaimPolicy:    fmt.Sprintf("%s", *sc.ReclaimPolicy),
			Labels:           labelsStr,
			Annotations:      annotationsStr,
			CreateTime:       sc.CreationTimestamp.Format("2006-01-02 15:04:05"),
		}
		bbb = append(bbb, *Items)
	}
	return bbb, err
}

func PersistentVolumeList(kubeconfig string) ([]PersistentVolume, error) {
	clientset := common.ClientSet(kubeconfig)
	pvList, err := clientset.CoreV1().PersistentVolumes().List(context.TODO(), metav1.ListOptions{})
	if err != nil {
		log.Printf("list deployment error, err:%v\n", err)
	}
	var bbb = make([]PersistentVolume, 0)
	for _, pv := range pvList.Items {
		var labelsStr string
		for kk, vv := range pv.Labels {
			labelsStr += fmt.Sprintf("%s:%s,", kk, vv)
		}
		var annotationsStr string
		for k2, v2 := range pv.Annotations {
			annotationsStr += fmt.Sprintf("%s:%s,", k2, v2)
		}
		var accessModeStr string
		for _, v3 := range pv.Spec.AccessModes {
			accessModeStr += fmt.Sprintf("%s", v3)
		}
		Items := &PersistentVolume{
			PvName:          pv.Name,
			Capacity:        pv.Spec.Capacity.Storage().String(),
			AccessMode:      accessModeStr,
			PvReclaimPolicy: fmt.Sprintf("%s", pv.Spec.PersistentVolumeReclaimPolicy),
			StorageClass:    pv.Spec.StorageClassName,
			Status:          fmt.Sprintf("%s", pv.Status.Phase),
			ClaimRef:        fmt.Sprintf("命名空间:%s<br>名称:%s", pv.Spec.ClaimRef.Namespace, pv.Spec.ClaimRef.Name),
			Labels:          labelsStr,
			Annotations:     annotationsStr,
			CreateTime:      pv.CreationTimestamp.Format("2006-01-02 15:04:05"),
		}
		bbb = append(bbb, *Items)
	}
	return bbb, err
}

func PersistentVolumeClaimList(kubeconfig, namespace, pvcName, labelsKey, labelsValue string) ([]PersistentVolumeClaim, error) {
	clientset := common.ClientSet(kubeconfig)
	if namespace == "" {
		//namespace = corev1.NamespaceDefault
		namespace = corev1.NamespaceAll
	}

	//设置ListOptions
	var listOptions = metav1.ListOptions{}
	if labelsKey != "" && labelsValue != "" {
		listOptions = metav1.ListOptions{
			LabelSelector: fmt.Sprintf("%s=%s", labelsKey, labelsValue),
		}
	}

	pvcList, err := clientset.CoreV1().PersistentVolumeClaims(namespace).List(context.TODO(), listOptions)
	if err != nil {
		log.Printf("list deployment error, err:%v\n", err)
	}
	var bbb = make([]PersistentVolumeClaim, 0)
	for _, pvc := range pvcList.Items {

		//搜索
		if pvcName != "" {
			if !strings.Contains(pvc.Name, pvcName) {
				continue
			}
		}

		var labelsStr string
		for kk, vv := range pvc.Labels {
			labelsStr += fmt.Sprintf("%s:%s,", kk, vv)
		}
		var annotationsStr string
		for k2, v2 := range pvc.Annotations {
			annotationsStr += fmt.Sprintf("%s:%s,", k2, v2)
		}
		var accessModeStr string
		for _, v3 := range pvc.Spec.AccessModes {
			accessModeStr += fmt.Sprintf("%s", v3)
		}
		Items := &PersistentVolumeClaim{
			PvcName:      pvc.Name,
			NameSpace:    pvc.Namespace,
			Capacity:     pvc.Status.Capacity.Storage().String(),
			AccessMode:   accessModeStr,
			StorageClass: *pvc.Spec.StorageClassName,
			Status:       fmt.Sprintf("%s", pvc.Status.Phase),
			VolumeName:   pvc.Spec.VolumeName,
			Labels:       labelsStr,
			Annotations:  annotationsStr,
			CreateTime:   pvc.CreationTimestamp.Format("2006-01-02 15:04:05"),
		}
		bbb = append(bbb, *Items)
	}
	return bbb, err
}
